package com.cmos.um.utils;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;

/**
 * 类：工具类
 */
public class DataUtil {

    private static Logger logger = Logger.getLogger(DataUtil.class); // 日志对象

    /**
     * 【工具】检查 keyList 中的字段是否在 paramsMap 中都有
     *
     * @param paramsMap 被检查的MAP
     * @param keyList   必须包含的MAP
     * @return boolean   是否都有
     */
    public static boolean validateName(Map<String, Object> paramsMap, List<String> keyList) {
        for (String key : keyList)
            if (!paramsMap.containsKey(key))
                return false;
        return true;
    }

    /**
     * 【工具】 将任意对象转换为Json字符串，再从Json字符串转换为MAP对象——整理对象为MAP
     *
     * @param obj 要被整理的对象
     * @return Map       整理后的MAP型的对象
     * @throws Exception 有错误时抛出异常
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> json2Map(Object obj) throws Exception {
        //1 检查输入是否为空
        if (obj.toString().isEmpty())
            return null;

        //2 将任意对象转换为Json字符串，再从Json字符串转换为MAP对象
        Map<String, Object> objMap = null;
        try {
            objMap = JSON.parseObject(obj.toString(), Map.class);
        } catch (Exception e) {
            String s = "利用DataUtil.json2Map()重新封装对象（为MAP）时出错，" + e.getMessage() + "，原本要转换的对象为：" + obj.toString() + "。";
            logger.error(s);
            throw new Exception(s);
        }

        //3 函数正常结束，返回MAP形式的参数
        return objMap;
    }

    /**
     * 【工具】 将任务对象转化为Json字符串，再从Json字符串转换为List<Map<String,Object>>对象
     *
     * @param obj 要被整理的对象
     * @return List<Map<String, Object>> 整理后的List<Map<String, Object>>型对象
     * @throws Exception 有错误时抛出异常
     */
    @SuppressWarnings("unchecked")
    public static List<Map<String, Object>> json2List(Object obj) throws Exception {
        //1 检查输入参数
        if (obj == null || obj.toString().isEmpty()) {
            String s = "在利用json2List()函数将对象转换为List<Map<String, Object>>型对象时出错，输入的参数obj为空";
            logger.error(s);
            throw new Exception(s);
        }

        //2 转换..
        List<Map<String, Object>> jsonList = new ArrayList<>(); // 转换后的对象
        try {
            //a 先将对象转换为对象数组
            List<Object> initList = JSONArray.parseArray(obj.toString(), Object.class);

            //b 逐个将每个对象转成MAP型
            for (Object initObjec : initList)
                jsonList.add((Map<String, Object>) initObjec);
        } catch (Exception e) {
            String s = "在利用json2List()函数将对象转换为List<Map<String, Object>>型对象时出错，" + e.getMessage();
            logger.error(s);
            throw new Exception(s);
        }

        //3 函数正常结束，返回转换后形成的对象
        return jsonList;
    }

    @SuppressWarnings("unchecked")
    public static ArrayList<Object> json2ArrayList(Object json) throws Exception {
        ArrayList<Object> jsonArrayList = null;
        try {
            jsonArrayList = JSON.parseObject(json.toString(), ArrayList.class);
        } catch (Exception e) {
            logger.error("json2ArrayList解析json时出错:" + e.getMessage());
            throw new Exception("json格式不正确，解析成ArrayList出错。" + e.getMessage());
        }
        return jsonArrayList;
    }

    /**
     * 【工具】JSON字符窜+表名 → 插入动态数据库Map<表名,List<Map<字段名,字段值>>>
     *
     * @param busicode 表名
     * @param jsonStr  JSON字符串
     * @return Map      MAP形式的数据，形如：MAP<表名，LIST<MAP<字段名，字段值>>>
     */
    public static Map<String, List<Map<String, Object>>> getFormatParams(String busicode, String jsonStr) throws Exception {
        //1 检查输入参数
        if (busicode == null || busicode.isEmpty())
            throw new Exception("在调用DataUtil::getFormatParams(busicode,jsonStr)函数时，表名（busicode）参数为空");
        if (jsonStr == null || jsonStr.isEmpty())
            throw new Exception("在调用DataUtil::getFormatParams(busicode,jsonStr)函数时，JSON字符串（jsonStr）参数为空");

        //2 将输入的对象解析重构为MAP型
        Map<String, Object> fieldMap = null;
        try {
            fieldMap = JSON.parseObject(jsonStr.toString());
        } catch (Exception e) {
            String msg = "在调用DataUtil.getFormatParams()函数将对象解析重构为MAP对象时出错，" + e.getMessage() + "，将返回空的数据，要解析的数据为：" + busicode + "|" + jsonStr.toString() + "。";
            logger.error(msg);
            throw new Exception(msg);
        }

        //3 将数据放入到（适合动态Insert的Map<表名,List<Map<字段名,字段值>>>）数据结构中
        List<Map<String, Object>> fieldList = new ArrayList<>();
        fieldList.add(fieldMap);
        Map<String, List<Map<String, Object>>> dbData = new HashMap<>();
        dbData.put(busicode, fieldList);

        //4 函数正常结束，返回MAP形式的数据
        return dbData;
    }

    /**
     * 【工具】MAP形式的数据库表字段+表名 → 插入动态数据库Map<表名,List<Map<字段名,字段值>>>
     *
     * @param busicode 表名
     * @param fieldMap 参数集MAP
     * @return Map      MAP形式的数据，形如：MAP<表名，LIST<MAP<字段名，字段值>>>
     */
    public static Map<String, List<Map<String, Object>>> getFormatParams(String busicode, Map<String, Object> fieldMap) throws Exception {
        //1 检查输入参数
        if (busicode == null || busicode.isEmpty())
            throw new Exception("在调用DataUtil::getFormatParams(busicode,fieldMap)函数时，表名（busicode）参数为空");
        if (fieldMap == null || fieldMap.isEmpty())
            throw new Exception("在调用DataUtil::getFormatParams(busicode,fieldMap)函数时，MAP集合（fieldMap）参数为空");

        //2 将数据放入到（适合动态Insert的Map<表名,List<Map<字段名,字段值>>>）数据结构中
        List<Map<String, Object>> fieldList = new ArrayList<>();
        fieldList.add(fieldMap);
        Map<String, List<Map<String, Object>>> dbData = new HashMap<>();
        dbData.put(busicode, fieldList);

        //3 函数正常结束，返回MAP形式的数据
        return dbData;
    }

    public static Object addParams(String newParam, Object newParams, Object jsonStr) throws Exception {
        Map<String, Object> fieldMap = null;
        try {
            fieldMap = JSON.parseObject(jsonStr.toString());
        } catch (Exception e) {
            logger.error("addParams出错:" + e.getMessage());
            throw new Exception("json格式不正确，addParams出错。" + e.getMessage());
        }
        fieldMap.put(newParam, newParams);
        return fieldMap.toString();
    }

    /**
     * 【工具】获得当前时刻
     *
     * @return String 当前时刻的字符串（yyyy-MM-dd HH:mm:ss）
     */
    public static String now() {
        return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date());
    }


    /**
     * 【工具】标准时间格式转化为新方时间格式
     *
     * @param time 格式为YYYY-MM-dd hh24:mm:ss的时间字符串
     * @return String 格式为YYYYMMddhhmmss的时间字符串
     */
    public static String timeS2C(String time) {
        if (time == null || time.isEmpty())
            return simpleSQL.cinNowTime();
        return time.replaceAll("[/\\s-:]", "");
    }


    /**
     * 【工具】创建文件并写入
     * @param filetxt 要写入的内容
     * @param path 文件地址
     */
    public static void writeFile(String filetxt, String path) {
        FileWriter fw = null;
        try {
            //如果文件存在，则追加内容；如果文件不存在，则创建文件
            File f = new File(path);
            fw = new FileWriter(f, true);
        } catch (IOException e) {
            e.printStackTrace();
        }
        PrintWriter pw = new PrintWriter(fw);
        pw.println(filetxt);
        pw.flush();
        try {
            fw.flush();
            pw.close();
            fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
